package com.yang.limit.aspect;


import com.yang.limit.annotation.RequestLimit;
import com.yang.limit.dto.RequestLimitDTO;
import com.yang.limit.factory.RequestLimitFactory;
import com.yang.limit.service.RequestLimitService;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

@Aspect
@Slf4j
public class RequestLimitAspect {

    @Autowired
    private RequestLimitFactory factory;

    /**
     * 切入点
     */
    @Pointcut(value = "@annotation(com.yang.limit.annotation.RequestLimit)")
    public void requestLimit(){
    }

    @Before("requestLimit()")
    public void before(JoinPoint joinPoint){
        log.info("before................................");
        Signature signature = joinPoint.getSignature();
        MethodSignature methodSignature = (MethodSignature) signature;
        Method targetMethod = methodSignature.getMethod();

        RequestLimit limiter = targetMethod.getAnnotation(RequestLimit.class);
        log.info("限流方式：【{}】", limiter.type().getDesc());
        //根据类型获取限流服务实例
        RequestLimitService service = factory.build(limiter.type());
        if (service == null) {
            log.info("没有【{}】限流操作类型，直接放行", limiter.type());
        } else {
            RequestLimitDTO dto = new RequestLimitDTO();
            dto.setLimiter(limiter);
            dto.setKey(signature.getName());
            if (service.checkIsRequestLimit(dto)) {
                throw new RuntimeException("当前使用的是【" + limiter.type().getDesc() + "】限流控制策略");
            }
        }
    }

}
